package com.hxci.hospital.controller;

import com.hxci.hospital.pojo.Patient;
import com.hxci.hospital.service.PatientService;
import com.hxci.hospital.tool.HospitalTools;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@RestController
@RequestMapping("/hospital/ai")
public class HospitalAIController {
    private final ChatClient chatClient;

    @Autowired
    private PatientService patientService;

    public HospitalAIController(ChatClient.Builder chatClientBuilder, VectorStore vectorStore, ChatMemory chatMemory) {
        this.chatClient = chatClientBuilder
                .defaultSystem("""
                        您是"哈尔滨信息工程学院医院门诊系统"的智能挂号助手。请以友好、乐于助人且专业的方式来回复。
                        您正在通过在线聊天系统与患者互动。
                        在帮助患者挂号之前，您必须始终从患者处获取以下信息：
                        1. 患者姓名
                        2. 性别
                        3. 年龄
                        4. 联系电话
                        5. 身份证号
                        6. 症状描述
                        7. 希望就诊的科室
                        8. 希望就诊的日期和时间

                        挂号成功后，请告知患者挂号成功，并提供就诊信息。
                        使用提供的功能完成挂号操作。
                        如果需要，可以调用相应函数完成辅助动作。
                        请讲中文。
                        """)
                .defaultAdvisors(
                        new PromptChatMemoryAdvisor(chatMemory),
                        new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())
                )
                .defaultFunctions("makeAppointment") // FUNCTION CALLING
                .build();
    }

    @GetMapping(value = "/generateStreamAsString", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> generateStreamAsString(@RequestParam(value = "message", defaultValue = "您好，有什么可以帮助您的吗？") String message) {
        System.out.println(message + "==========================");
        Flux<String> content = chatClient.prompt()
                .advisors(a -> a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
                .user(message)
                .stream()
                .content();
        return content.concatWith(Flux.just("[complete]"));
    }
}
